Windows access token 介绍及利用
1 背景
我第一次看到 windows access token 是在打靶场的时候,通过 msf 的工具获取主机上管理员用户的令牌来伪造管理员权限,并通过进程迁移实现完全的提权。
当时对于 windows access token 还有很多疑问,这里尝试对其机制进行一个比较完整的解释,以及总结一下如何利用这个 access token 进行用户的伪造。
.
.
2 Windows access token 机制介绍
一 简介
access token 翻译过来就是访问令牌,官方给的解释是:一个进程或者线程的描述安全上下文(the security context)的对象。安全上下文可以理解成一段关于系统安全的信息。
令牌中的信息包括与进程或线程相关的用户账户的身份和权限。
当用户登录系统之后,windows 会产生一个令牌(access token)颁发给用户,这是通过 LSASS.exe 这个程序完成的。
然后这个用户开启的所有进程都会从用户那里复制一份 access token 给进程自己。这也是为啥有时候 A 用户的进程 B 用户没有权限去使用,因为 A 、B 用户的 access token 不同,而且该进程的代码中写了令牌校验的机制。
当一个程序(线程)需要和系统安全相关的对象进行交互,或者需要权限执行某些系统任务的时候,windows 系统就会通过 access token 去校验身份。至于具体的校验机制,后面再补充。
.
二 令牌包含的内容
- The security identifier (SID) for the user’s account
- 用户帐户的安全标识符(SID)
- SIDs for the groups of which the user is a member
- 用户所属的组的SID
- A logon SID that identifies the current logon session
- 用于标识当前登录会话的登录SID
- A list of the privileges held by either the user or the user’s groups
- 用户或用户组所拥有的权限列表
- An owner SID
- 所有者SID
- The SID for the primary group
- 主要组的SID
- The default DACL that the system uses when the user creates a securable object without specifying a security descriptor
- 访问控制列表
- The source of the access token
- 访问令牌的来源
- Whether the token is a primary or impersonation token
- 令牌是主要令牌还是模拟令牌
- An optional list of restricting SIDs
- 限制SID的可选列表
- Current impersonation levels
- 目前的模拟等级
- Other statistics
- 其他统计数据
.
.
3 主要令牌和模拟令牌
一 主要令牌 (primary token)
1 主要令牌的产生
主要令牌是用户登录的时候系统就会给该用户先颁发一个主要令牌
这里的登录主要指交互式登录,比如本地登录,远程桌面
.
这里补充一下关于主要令牌产生的细节
用户使用凭据(用户密码)进行认证 –> 登录 session 创建 –> windows 返回用户的 sid 和用户所在组的 sid –> LSA 创建一个 Access token —> 使用凭据成功认证 –> 登录 session —> token —> 进程、线程
.
2 主要令牌的传递
用户登录之后,用户开启的所有进程都会先复制一份主要令牌给进程自己
因此每个进程都有一个主要令牌,用于描述与该进程关联的用户帐户的安全上下文。
默认情况下,当进程的线程与安全对象进行交互时,系统使用主令牌。
此外,主要令牌有个机制,前面我们说了每个进程都复制了一份创建者的主要令牌,而这些进程开启的子进程也会从父进程那继承一份主要令牌(前提是子进程的代码中没有指定使用特定的 access token,且这个过程还是有 LSASS.exe 执行的)
.
二 模拟令牌(impersonation token)
1 模拟令牌的定义
主要令牌很好理解,就是用户登录后系统颁发的描述安全信息的对象
而模拟令牌的定义则是:
当进程(线程)需要以其他用户的身份获取系统资源或执行某些功能的时候,就需要用到其他用户的模拟令牌
impersonation tokens: these allow a particular process(or thread in a process) to gain access to resources using the token of another (user/client) process
注意:一个模拟其他用户(客户端)的进程或线程是同时具有自己的主令牌和其他用户的模拟令牌的
.
2 模拟令牌的产生
当用户注销后,系统将会使主令牌切换为模拟令牌并保存在系统中,
且不会将令牌清除,只有在重启机器后才会清除。
.
3 为什么会有模拟令牌?(我们拿模拟令牌来干嘛)
impersonation token is for impersonation .(模拟令牌是用来模拟的)
看起来像句废话,但是这里重点在于 模拟(impersonation) 这个行为
官方原文:
Impersonation is the ability of a thread to execute using different security information than the process that owns the thread. Typically, a thread in a server application impersonates a client. This allows the server thread to act on behalf of that client to access objects on the server or validate access to the client’s own objects.
大概意思是,线程有时候要使用到其他用户的安全信息时,就会需要到模拟令牌。模拟(impersonation)就是去线程去模拟其他用户的身份,从而可以更加方便地执行各种功能逻辑。
简单来说就是我们希望不同用户(客户端)来访问主机上的服务时,服务可以模拟客户端的身份去访问服务,而不是用自己的主进程Token身份去访问,从而解决一些权限问题。
.
4 模拟令牌的级别
我们说用户注销之后会产生模拟令牌,且模拟令牌的意义就是用来被线程模拟其他用户身份的,但是并不是所有的用户都想被线程模拟身份。
所以模拟令牌就设置了一个级别机制
只有当模拟令牌具有 Impersonation 和 Delegation 级别的时候才可以被用来模拟。
.
模拟令牌的所有级别:
- SecurityAnonymous:current user/client cannot impersonate another user/client
- 其他用户(客户端)无法通过这个模拟令牌模拟该用户(模拟令牌的所有者)或者客户端。
- SecurityIdentification:current user/client can get the identity and privileges of a client, but cannot impersonate the client
- 其他用户(客户端)可以通过这个模拟令牌获取到该用户的身份信息和权限,但是不能伪造该用户(客户端)
- SecurityImpersonation:current user/client can impersonate the client’s security context on the local system
- 其他用户可以在本地系统上通过这个模拟令牌伪造该用户,伪造指的是获取到该用户的安全上下文
- SecurityDelegation:current user/client can impersonate the client’s security context on a remote system
- 其他用户可以在远程系统上通过这个模拟令牌伪造该用户
.
.
4 不同登录方式获取的令牌
一 登录方式
- 交互式登录
- console login (type 2)
- rdp login (type 10)
- psexec (type 2)
- 网络登录
- wmi (type 3)
- winrm (type 3)
.
二 各自获取的令牌种类
primary token 这种令牌通常用于本地及远程 RDP 登录
impersonation token 这种则通常用于各种非交互式的登录,比如,netuse,wmi,winrm等等
.
.
5 盗取模拟令牌攻击 (Token Kidnapping)
一 原理
经过上面的介绍,
我们知道了用户注销的时候会在系统上保存一个模拟令牌,而在特定情况下,当前用户(进程)又可以使用模拟令牌来伪造模拟令牌所属者的身份。
所以这里就存在一个提权的可能。
假设现在拿到主机的一个普通用户 Normal 的权限
只要满足下面几点条件,就能够通过盗取管理员用户的模拟令牌来实现提权
- Normal 用户拥有 SeImpersonatePrivilege 权限,这意味着该用户能够使用别人的模拟令牌
- 管理员用户注销之后,系统并没有重启,此时管理员的模拟令牌仍保留在系统上
- 管理员的模拟令牌的等级是 SecurityDelegation (远程)或者 SecurityImpersonation(本地)
.
不过需要注意的是,有时候盗取管理员令牌之后,仍不算百分百的提权。还需要进行进程迁移才能够实现百分百提提权。
关于这点我没有找到特别明确的解释,以下的解释只是个人理解
首先用户登录的时候,系统会给当前用户颁发 primary token (主要令牌),然后该用户开启的所有进程都会复制一份这个 token 给进程自己。
而当用户注销后,系统将会使主令牌切换为模拟令牌,并保存在系统上。系统此时不会将令牌清除,只
有在重启机器后才会清除。
所以我们只要能够拿到保存在系统上的其他用户的模拟令牌(impersonation token),就能够对该用户
进行一定程度上的伪造。
为啥说是一定程度,而不是完全伪造呢?
因为有的进程是认模拟令牌(impersonation token)的,所以对于这些进程,只要有模拟令牌,就会被进程认为当前用户是合法的,并允许当前用户使用该进程。
但并不是所有的进程都认,有很多进程只认 primary token(主要令牌),所以只有模拟令牌的话,并不能算完全伪造目标用户。
后续如果要完全模拟的话,还是需要进行进程迁移。
由于进程有个机制,在进程被创建的时候,如果代码没有写明要指定获取某个特定的令牌,那么该进程就会从父进程那里继承父进程的令牌。
所以,只要我们能够进程迁移到拥有目标用户主要令牌的进程上,我们就能通过主要令牌完全伪造目标用户了。
.
.
二 实战 (取自 tryhackme Alfred 部分靶场笔记)
这里使用 tryhackme 的 Alfred 靶场进行演示,
当我们拿到一个 meterpreter session , sessions -i 1 连上
getuid 命令查看下当前用户,发现是普通用户 alfred\bruce
然后在 meterpreter shell 中打开一个 cmd 命令行 shell
接下来查看当前用户的权限,看看是否有 SeImpersonatePrivilege 权限 (whoami /priv 命令)
.
发现的确存在,那么当前用户就可以使用系统中保存的其他用户的模拟令牌
接下来退出 cmd shell ,并使用 msf 中的 incognito 模块尝试列举都有什么用户的模拟令牌
load incognito 加载 incognito 模块
list_tokens -g 列举系统保存了什么用户的模拟令牌
可以看到,
使用 list_tokens -g 命令列举系统保存了什么模拟令牌之后,
出现了两个表,
Impersonation Tokens Availlable 和
Delegation Tokens Available
其实他们都是模拟令牌,只不过级别不一样。
Delegation 是最高级别,允许当前用户在远程系统上来使用这个模拟令牌
我们主要查看 Delegation 中的模拟令牌,因为是远程连接进去的
恰好这里有一个属于管理员的模拟令牌
用它!
使用如下命令
impersonate_token “指定的用户” 拿取制定用户的模拟令牌
impersonate_token “BUILTIN\Administrators” 拿取 Administrators 的 impersonation token
.
成功拿到管理员的模拟令牌之后
此时使用 getuid 命令,查看当前用户是不是管理员
可以看到,确实显示的是管理员
但是即使是现在,我们拿到了管理员的模拟令牌,也不一定能够完全伪造管理员的身份
就像之前说的那样,有些进程通过 impersonation token (模拟令牌) 来认当前用户身份,
而有些进程只认 primary token (主要令牌) 来确认用户的身份
所以我们需要进行进程迁移
.
那么现在的情况是,我们只是通过拿取模拟令牌实现了一定程度上的伪造管理员用户
接下来就是通过进程迁移,迁移到拥有管理员用户的主要令牌的进程
通过进程会继承父进程主要令牌的机制,完全伪造管理员
实现百分百的提权
这里推荐一个最保险的进程,services.exe
.
先用 ps 命令查看进程:
.
migrate 668 迁移到 services.exe 去
此时已经拿到了管理员的主要令牌了,
已经可以百分百伪造管理员了
接下来为了进一步确认,尝试去读取靶标 (C:\Windows\System32\config\root.txt)
.
开启一个 cmd shell
type C:\Windows\System32\config\root.txt
即可成功读取到靶标
.
.
6 参考文章
https://www.anquanke.com/post/id/204721
https://hackergu.com/powerup-stealtoken-rottenpotato/
https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens
https://docs.microsoft.com/en-us/windows/win32/secauthz/client-server-access-control
https://docs.microsoft.com/en-us/windows/win32/secauthz/impersonation-levels
https://rootclay.gitbook.io/windows-access-control/access-token
https://www.anquanke.com/post/id/204721
https://msrc-blog.microsoft.com/2009/04/14/token-kidnapping/
http://www.4k8k.xyz/article/qq_41874930/111963586
https://www.offensive-security.com/metasploit-unleashed/fun-incognito/
https://payloads.online/archivers/2018-11-30/1/#0x03-windows-access-token
https://www.exploit-db.com/papers/42556
https://lengjibo.github.io/token/
https://www.geekby.site/2020/05/域渗透之-windows-access-token-攻击/
https://shanfenglan.blog.csdn.net/article/details/111926058
https://3gstudent.github.io/渗透技巧-Windows九种权限的利用
https://blog.csdn.net/sch0120/article/details/70226903
.
.
/